package com.quick.db.dao;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.quick.db.L;
import com.quick.db.annotation.Column;
import com.quick.db.info.ColumnInfo;
import com.quick.db.info.TableInfo;
import com.quick.db.utils.TableUtils;

import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

public class Dao<T> {
	private Class<T> mClazz;
	private SQLiteDatabase mDb;
	private TableInfo mTableInfo;

	public Dao(Class<T> clazz, SQLiteDatabase db) {
		mClazz = clazz;
		mDb = db;
		buildTableInfo(clazz);
	}

	private void buildTableInfo(Class<T> clazz) {
		mTableInfo = new TableInfo();
		mTableInfo.tableName = TableUtils.getTableName(clazz);
		ArrayList<ColumnInfo> list = new ArrayList<ColumnInfo>();
		ColumnInfo item = null;
		Field[] fields = clazz.getDeclaredFields();
		if (fields != null && fields.length > 0) {
			for (Field field : fields) {
				field.setAccessible(true);
				item = new ColumnInfo();
				item.originName = field.getName();
				item.originType = field.getType();
				Column column = field.getAnnotation(Column.class);
				if (column != null) {
					item.dbName = column.value();
					if (column.primaryKey()) {
						mTableInfo.primaryKey = new ColumnInfo();
						mTableInfo.primaryKey.originName = field.getName();
						mTableInfo.primaryKey.originType = field.getType();
						mTableInfo.primaryKey.dbName = column.value();
					}
				}
				list.add(item);
			}
		}
		mTableInfo.list = list;
		if (mTableInfo.primaryKey == null) {
			throw new NullPointerException("该表中没有主键");
		}
	}

	/** 批量查询 */
	public List<T> queryList() {
		ArrayList<T> results = new ArrayList<T>();
		mDb.beginTransaction();
		try {
			T obj = null;
			Cursor cursor = mDb.query(mTableInfo.tableName, null, null, null,
					null, null, null);
			if (cursor != null) {
				while (cursor.moveToNext()) {
					try {
						obj = mClazz.newInstance();
						if (mTableInfo.list != null
								&& mTableInfo.list.size() > 0) {
							for (ColumnInfo item : mTableInfo.list) {
								TableUtils.setFieldValue(mClazz, item, obj,
										cursor);
							}
						}
						results.add(obj);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
				if (cursor != null) {
					cursor.close();
				}
			}
		} finally {

			mDb.endTransaction();
		}
		return results;
	}

	/** 批量插入 */
	public long[] insertAll(List<T> list) {
		if (list == null || list.size() == 0) {
			return null;
		}
		int size = list.size();
		long[] results = new long[size];
		mDb.beginTransaction();
		try {
			for (int i = 0; i < size; i++) {
				results[i] = insert(list.get(i));
			}
			mDb.setTransactionSuccessful();
		} finally {
			mDb.endTransaction();
		}
		return results;
	}

	/** 单一插入 */
	public long insert(T obj) {
		if (obj == null) {
			return 0;
		}
		ContentValues values = TableUtils.getContentValue(obj);
		return mDb.insert(mTableInfo.tableName, null, values);
	}

	/** 批量修改 */
	public int[] updateAll(List<T> list, ContentValues values) {
		if (list == null || list.size() == 0) {
			return null;
		}
		int size = list.size();
		int[] results = new int[size];
		mDb.beginTransaction();
		try {
			for (int i = 0; i < size; i++) {
				results[i] = update(list.get(i), values);
			}
			// 设置事务标志为成功，当结束事务时就会提交事务
			mDb.setTransactionSuccessful();
		} finally {
			mDb.endTransaction();
		}
		return results;
	}

	/** 批量更新专用 */
	private int update(T obj, ContentValues values) {
		if (obj == null || values == null) {
			return 0;
		}
		String value = TableUtils.getPrimaryKeyValue(mClazz, obj,
				mTableInfo.primaryKey.originName);
		if (value == null) {
			return -1;
		}
		return mDb.update(mTableInfo.tableName, values,
				mTableInfo.primaryKey.dbName + "=?", new String[] { value });
	}

	/** 单一修改 */
	public int update(T obj) {
		if (obj == null) {
			return 0;
		}
		ContentValues values = TableUtils.getContentValue(obj);
		String value = TableUtils.getPrimaryKeyValue(mClazz, obj,
				mTableInfo.primaryKey.originName);
		if (value == null) {
			return -1;
		}
		return mDb.update(mTableInfo.tableName, values,
				mTableInfo.primaryKey.dbName + "=?", new String[] { value });
	}

	/** 批量删除 */
	public int[] deleteAll(List<T> list) {
		if (list == null || list.size() == 0) {
			return null;
		}
		int size = list.size();
		int[] results = new int[size];
		mDb.beginTransaction();
		try {
			for (int i = 0; i < size; i++) {
				results[i] = delete(list.get(i));
			}
			mDb.setTransactionSuccessful();
		} finally {
			mDb.endTransaction();
		}
		return results;
	}

	/** 单一删除 */
	public int delete(T obj) {
		if (obj == null) {
			return 0;
		}
		String value = TableUtils.getPrimaryKeyValue(mClazz, obj,
				mTableInfo.primaryKey.originName);
		if (value == null) {
			return -1;
		}
		return mDb.delete(mTableInfo.tableName, mTableInfo.primaryKey.dbName
				+ "=?", new String[] { value });
	}
}
